package org.tangerinejunction.imstats.data;

import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.util.ArrayList;
import java.util.Calendar;

import org.tangerinejunction.imstats.logs.LogFile;

import prefuse.data.Graph;
import prefuse.data.Table;
import prefuse.data.tuple.TableTuple;

/**
 * An Account represents an instant messaging account with which the user has contact.
 * Accounts are associated with an instant messaging protocol, 
 * the name of the user's associated account and the name of the contact's account.
 * An Account is not to be confused with an @link Entity.
 * 
 * @author meganthorsen
 */
public class Account extends TableTuple implements Comparable<Account>, Externalizable
{
	public static final String PROTOCOL_KEY = "Protocol";
	public static final String MY_ACCOUNT_NAME_KEY = "My account name";
	public static final String NAME_KEY = "Their account name";
	public static final String LOG_FILES_KEY = "Log files";
	public static final String ENTITY_KEY = "Entity";
	public static final String FILTERED = "Filtered";
	public static final String MIN_LOG_DATE = "Min log date";
	
	public Account()
	{
		super();
	}

	/**
	 * 
	 * @param protocol	name of the instant messaging protocol associated with this Account
	 * @param myAccountName	name of this user's instant messaging account
	 * @param name	name of the conversation partner's instant messaging account
	 * @param table	the Prefuse Table backing the Accounts
	 * @param graph	the Prefuse Graph backing the Accounts
	 * @param row	the row in the Table associated with this Account
	 * @param entity	the Entity to which this Account belongs
	 */
	public void init(String protocol, String myAccountName, String name, Table table, Graph graph, int row, Entity entity)
	{
		init(table, graph, row);
		setString(PROTOCOL_KEY, protocol);
		setString(MY_ACCOUNT_NAME_KEY, myAccountName);
		setString(NAME_KEY, name);
		set(LOG_FILES_KEY, new ArrayList<LogFile>());
		set(ENTITY_KEY, entity);
		set(FILTERED, new Boolean(false));
        set(MIN_LOG_DATE, null);
	}
	
	/**
	 * 
	 * @return	the name of the instant messaging protocol used with this Account
	 */
	public String getProtocol()
	{
		return getString(PROTOCOL_KEY);
	}
	
	/**
	 * 
	 * @return	the name of the user's instant messaging account
	 */
	public String getMyAccountName()
	{
		return getString(MY_ACCOUNT_NAME_KEY);
	}
	
	/**
	 * 
	 * @return	the name of the conversation partner's instant messaging account
	 */
	public String getName()
	{
		return getString(NAME_KEY);
	}
	
	/**
	 * 
	 * @return	the list of LogFiles belonging to this Account
	 */
	public ArrayList<LogFile> getLogFiles()
	{
		return (ArrayList<LogFile>)get(LOG_FILES_KEY);
	}
	
	/**
	 * 
	 * @return	the Entity to which this Account belongs
	 */
	public Entity getEntity()
	{
		return (Entity)get(ENTITY_KEY);
	}
	
	/**
	 * 
	 * @return	whether this Account has been filtered from chart views
	 */
	public boolean getFiltered()
	{
		return (Boolean)get(FILTERED);
	}
	
	public Calendar getMinLogDate()
	{
	    return (Calendar)get(MIN_LOG_DATE);
	}
	
	/**
	 * 
	 * @param logFile	the LogFile to add to this Account
	 */
	public void addLogFile(LogFile logFile)
	{
		ArrayList<LogFile> logFiles = (ArrayList<LogFile>)get(LOG_FILES_KEY);
		if (logFiles == null)
			logFiles = new ArrayList<LogFile>();
		int fileIndex = findLogFile(logFiles, logFile);
		if (fileIndex < 0)
			logFiles.add(logFile);
		else
			logFiles.set(fileIndex, logFile);
		set(LOG_FILES_KEY, logFiles);
		if (getMinLogDate() == null || logFile.getDate().before(getMinLogDate()))
		    set(MIN_LOG_DATE, logFile.getDate());
	}
	
	/**
	 * 
	 * @param logFiles	the list of LogFiles to search
	 * @param targetFile	the LogFile we want to find
	 * @return
	 */
	protected int findLogFile(ArrayList<LogFile> logFiles, LogFile targetFile)
	{
		for (LogFile file : logFiles)
		{
			if (file.getAbsolutePath().equals(targetFile.getAbsolutePath()))
				return logFiles.indexOf(file);
		}
		return -1;
	}
	
	public String toString()
	{
		return getName();
	}

	public int compareTo(Account account) 
	{
		return this.getName().compareTo(account.getName());
	}

	public void readExternal(ObjectInput arg0) throws IOException,
			ClassNotFoundException 
	{
		// TODO Auto-generated method stub
		
	}

	public void writeExternal(ObjectOutput out) throws IOException 
	{
		/*
		out.writeObject(getProtocol());
		out.writeObject(getMyAccountName());
		out.writeObject(getName());
		*/
		//out.writeObject(getLogFiles());
		//out.writeObject(getEntity());
	}
}
